package net.zabuchy.issue.action;
 
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.zabuchy.IssueHelper.IssueIterations;
import net.zabuchy.IssueHelper.IssuePriorities;
import net.zabuchy.IssueHelper.IssueStatuses;
import net.zabuchy.IssueHelper.IssueTeams;
import net.zabuchy.IssueHelper.IssueTypes;
import net.zabuchy.helper.ParamNames;
import net.zabuchy.helper.SessionHelper;
import net.zabuchy.issue.bo.IssueBo;
import net.zabuchy.issue.entity.Attachment;
import net.zabuchy.issue.entity.Issue;
import net.zabuchy.issue.entity.IssueDetail;
import net.zabuchy.issue.entity.IssueLink;
import net.zabuchy.issue.entity.Notification;
import net.zabuchy.iteration.entity.Iteration;
import net.zabuchy.user.bo.UserBo;
import net.zabuchy.user.entity.User;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.springframework.beans.factory.annotation.Autowired;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
 

public class EditIssueAction extends  ActionSupport 
	implements ServletRequestAware,ServletResponseAware{ 
 
	private static final Logger LOGGER = Logger.getLogger(EditIssueAction.class.getName());
 
	@Autowired
    private SessionHelper sessionBean;
	@Autowired
	private IssueBo issueBo;
	@Autowired
	private UserBo userBo;
    
	private HttpServletRequest request;
    private HttpServletResponse response;
    
    private int issueId;
	private String author;
	private boolean confirmed;
	private Date creationDate;
	private int customerId;
	private String description;
	private int estimationHours;
	private Date estimationTime;
	private String priority;
	private int projectId;
	private String status;
	private String team;
	private String title;
	private String type;
	private Iteration iteration;
	private IssueDetail issueDetail;
	private Set<User> users = new HashSet<User>(0); // user pracujacy nad issue, najczesciej bedzie tylko jeden
	private Set<Attachment> attachments = new HashSet<Attachment>(0);
	private Set<IssueLink> issueLinks = new HashSet<IssueLink>(0);
	private Set<Notification> notifications = new HashSet<Notification>(0);
	private Set<User> notificatedUsers = new HashSet<User>(0);
	
	/**********************************************************/	
	private int currentEffort;
	private String sourceCode;
	private String stepByStep;
	private String systemConfiguration;
	private String workaround;
	/**********************************************************/	
	private File fileUpload;
	private String fileUploadContentType;
	private String fileUploadFileName;
	/**********************************************************/	
	private Issue issue;
	private List<String> usersSystem = new ArrayList<String>(0);
	private Set<String> types = IssueTypes.getIssueTypes();
	private Set<String> teams = IssueTeams.getTeams();
	private Set<String> statuses = IssueStatuses.getStatuses();
	private Set<String> priorities = IssuePriorities.getPriorities();
	private Set<String> iterations = IssueIterations.getIterations();
	private String iterationSlt;
	private String addedUser;
	private int userId;
	private int attachmentId;
	private int link;
	private int issueLinksId; 
	private String comment;
	
	public String execute() {
		LOGGER.debug("addForm");
		
		String returnInputProjectForm = request.getParameter(ParamNames.EDIT_ISSUE_FORM);
		boolean returnForm = (returnInputProjectForm != null ? 
				Boolean.parseBoolean(returnInputProjectForm) : false);
		
		if(request.getParameter("issueId") != null) {
			returnForm = true;
		}
		
		List<User> tmp = userBo.findByCustomerId(sessionBean.getCustomerId());
		Iterator it = tmp.iterator();
		while(it.hasNext()) {
			User user = (User) it.next();
			usersSystem.add(user.getUsername());
		}
		
		if(returnForm) {
			issueId = Integer.parseInt(request.getParameter("issueId"));
			LOGGER.debug("issueId: ***** " + issueId);
			LOGGER.debug("clear all fields and return form");
			clearFields();
			getIssue(issueId);
			return Action.INPUT;
		}

		issue = issueBo.findById(issueId);
		issueDetail = issue.getIssueDetail();
		issue.setEstimationHours(estimationHours);
		issue.setEstimationTime(estimationTime);
		issue.setPriority(priority);
		issue.setProjectId(sessionBean.getProjectId());
		issue.setStatus(status);
		issue.setTeam(team);
		issue.setTitle(title);
		issue.setDescription(description);
		issue.setType(type);
		issue.setUsers(users);
		issue.setAttachments(attachments);
		issue.setIssueLinks(issueLinks);
		issue.setNotifications(notifications);
		LOGGER.debug("" + confirmed);
		byte confirmation = 0;
		if(confirmed)
			confirmation = 1;
		issue.setConfirmed(confirmation);
		
		if("Current iteration".equals(iterationSlt)) {
			issue.setIteration(sessionBean.getActualIteration());
		} else {
			issue.setIteration(sessionBean.getActualIteration()); ///Do zmiany!!!!!!!!
		}
		
		issueDetail.setCurrentEffort(currentEffort);
		issueDetail.setSourceCode(sourceCode);
		issueDetail.setStepByStep(stepByStep);
		issueDetail.setSystemConfiguration(systemConfiguration);
		issueDetail.setWorkaround(workaround);
		
		issue.setIssueDetail(issueDetail);
		issueDetail.setIssue(issue);
	
		issueBo.update(issue);
		issueId = issue.getIssueId();
		LOGGER.debug("issueId: " + issueId);
	
        return Action.SUCCESS;
    }
	
	public String addNotification() {
		
		LOGGER.debug("add notificatoins start");
		User user = userBo.findByUsername(addedUser);
		LOGGER.debug("user.userName " + user.getUsername());
		Notification notification = new Notification();
		notification.setUserId(user.getUserId());
		notification.setIssue(issue);
		issueBo.addNotification(notification);
		LOGGER.debug("notificationId: " + notification.getNotificationId());
		notifications.add(notification);
		issueBo.update(issue);
		
		notificatedUsers.add(user);
		return Action.SUCCESS;
	}
	
	public String removeNotification() {
		
		if (userBo == null) {
            return Action.ERROR;
        }
		Notification tmp = null;
        User user = userBo.findById(userId);
        Iterator it = notifications.iterator();
        while(it.hasNext()) {
        	Notification noti = (Notification) it.next();
        	if(noti.getUserId() == userId) {
        		tmp = noti;
        	}
        }
        notifications.remove(tmp);
        issueBo.deleteNotification(tmp);
        for(User us : notificatedUsers) {
        	if(us.getUserId() == userId) {
        		notificatedUsers.remove(us);
        	}
        }
        issueBo.update(issue);
		return Action.SUCCESS;
	}
	
	public String addAttachment() {
		LOGGER.debug("addAttachment;");
		LOGGER.debug("fileUpload: " + fileUpload.toString());
		LOGGER.debug("fileUploadContentType: " + fileUploadContentType);
		LOGGER.debug("fileUploadFileName: " + fileUploadFileName);
		Attachment attachment = new Attachment(fileUpload.toString(), fileUploadContentType, fileUploadFileName, issue);
		issueBo.addAttachment(attachment);
		attachments.add(attachment);
		issueBo.update(issue);
		return Action.SUCCESS;
	}
    
	public String removeAttachment() {
		if (issueBo == null || attachmentId == 0) {
            return Action.ERROR;
        }
		Attachment tmp = null;
		Iterator it = attachments.iterator();
		while(it.hasNext()) {
			Attachment attach = (Attachment) it.next(); 
			if(attach.getAttachmentId() == attachmentId) {
				tmp = attach;
			}
		}
		attachments.remove(tmp);
		issueBo.deleteAttachment(tmp);
        issueBo.update(issue);
		return Action.SUCCESS;
	}
	
	public String addIssueLink() {
		LOGGER.debug("addIssueLink;");
		LOGGER.debug("link: " + link);
		IssueLink issueLink = new IssueLink(comment, link, issue);
		
		issueBo.addLink(issueLink);
		issueLinks.add(issueLink);
		issueBo.update(issue);
		return Action.SUCCESS;
	}
	
	public String removeIssueLink() {
		if (issueBo == null || issueLinksId == 0) {
            return Action.ERROR;
        }
		IssueLink tmp = null;
		Iterator it = issueLinks.iterator();
		while(it.hasNext()) {
			IssueLink linkk = (IssueLink) it.next(); 
			if(linkk.getIssueLinksId() == issueLinksId) {
				tmp = linkk;
			}
		}
		issueLinks.remove(tmp);
		issueBo.deleteLink(tmp);
        issueBo.update(issue);
		return Action.SUCCESS;
	}
	
	private void clearFields() {
		//issueId = 0;
		creationDate = null;
		status = null;
		type = null;
		description = null;
		estimationHours = 0;
		estimationTime = null;
		priority = null;
		team = null;
		title = null;
		iteration = null;
		issueDetail = null;
		users = new HashSet<User>(0);
		attachments = new HashSet<Attachment>(0);
		issueLinks = new HashSet<IssueLink>(0);
		notifications = new HashSet<Notification>(0);
		
		currentEffort = 0;
		sourceCode = null;
		stepByStep = null;
		systemConfiguration = null;
		workaround = null;
	}
	
	private void getIssue(int issueId) {
		LOGGER.debug("Get issue with id: " + issueId);
		
		this.issue = issueBo.findById(issueId);
		this.confirmed = issue.getConfirmed() == 1 ? true : false;
		this.description = issue.getDescription();
		this.estimationHours = issue.getEstimationHours();
		this.estimationTime = issue.getEstimationTime();
		this.priority = issue.getPriority();
		this.status = issue.getStatus();
		this.team = issue.getTeam();
		this.title = issue.getTitle();
		this.type = issue.getType();
		this.iteration = issue.getIteration();
		this.issueDetail = issue.getIssueDetail();
		this.users = issue.getUsers();
		this.issueLinks = issue.getIssueLinks();
		this.notifications = issue.getNotifications();
		this.attachments = issue.getAttachments();
		for(Notification notify : notifications) {
			notificatedUsers.add(userBo.findById(notify.getUserId()));
			LOGGER.debug("notificatedUsers.size: " + notificatedUsers.size());
		}
		
		this.currentEffort = issueDetail.getCurrentEffort();
		this.sourceCode = issueDetail.getSourceCode();
		this.stepByStep = issueDetail.getStepByStep();
		this.systemConfiguration = issueDetail.getSystemConfiguration();
		this.workaround = issueDetail.getWorkaround();
	}
 
    public IssueBo getIssueBo() {
		return issueBo;
	}

	public void setIssueBo(IssueBo issueBo) {
		this.issueBo = issueBo;
	}
    
	public void setSessionBean(SessionHelper sessionBean) {
		this.sessionBean = sessionBean;
	}

	public SessionHelper getSessionBean() {
		return sessionBean;
	}

	public Integer getIssueId() {
		return issueId;
	}


	public void setIssueId(Integer issueId) {
		this.issueId = issueId;
	}


	public String getAuthor() {
		return author;
	}


	public void setAuthor(String author) {
		this.author = author;
	}


	public Date getCreationDate() {
		return creationDate;
	}


	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}


	public int getCustomerId() {
		return customerId;
	}


	public void setCustomerId(int customerId) {
		this.customerId = customerId;
	}


	public int getProjectId() {
		return projectId;
	}


	public void setProjectId(int projectId) {
		this.projectId = projectId;
	}


	public Set<User> getUsers() {
		return users;
	}


	public void setUsers(Set<User> users) {
		this.users = users;
	}


	public String getStatus() {
		return status;
	}


	public void setStatus(String status) {
		this.status = status;
	}


	public String getType() {
		return type;
	}


	public void setType(String type) {
		this.type = type;
	}

	
	 public void setServletRequest(HttpServletRequest request){
		  this.request = request;
		  }

		  public HttpServletRequest getServletRequest(){
		  return request;
		  }

		  public void setServletResponse(HttpServletResponse response){
		  this.response = response;
		  }

		  public HttpServletResponse getServletResponse(){
		  return response;
		  }


		public UserBo getUserBo() {
			return userBo;
		}


		public void setUserBo(UserBo userBo) {
			this.userBo = userBo;
		}


		public boolean getConfirmed() {
			return confirmed;
		}


		public void setConfirmed(boolean confirmed) {
			this.confirmed = confirmed;
		}


		public String getDescription() {
			return description;
		}


		public void setDescription(String description) {
			this.description = description;
		}


		public int getEstimationHours() {
			return estimationHours;
		}


		public void setEstimationHours(int estimationHours) {
			this.estimationHours = estimationHours;
		}


		public Date getEstimationTime() {
			return estimationTime;
		}


		public void setEstimationTime(Date estimationTime) {
			this.estimationTime = estimationTime;
		}


		public String getPriority() {
			return priority;
		}


		public void setPriority(String priority) {
			this.priority = priority;
		}


		public String getTeam() {
			return team;
		}


		public void setTeam(String team) {
			this.team = team;
		}


		public String getTitle() {
			return title;
		}


		public void setTitle(String title) {
			this.title = title;
		}


		public Iteration getIteration() {
			return iteration;
		}


		public void setIteration(Iteration iteration) {
			this.iteration = iteration;
		}


		public IssueDetail getIssueDetail() {
			return issueDetail;
		}


		public void setIssueDetail(IssueDetail issueDetail) {
			this.issueDetail = issueDetail;
		}


		public Set<Attachment> getAttachments() {
			return attachments;
		}


		public void setAttachments(Set<Attachment> attachments) {
			this.attachments = attachments;
		}


		public Set<IssueLink> getIssueLinks() {
			return issueLinks;
		}


		public void setIssueLinks(Set<IssueLink> issueLinks) {
			this.issueLinks = issueLinks;
		}


		public Set<Notification> getNotifications() {
			return notifications;
		}


		public void setNotifications(Set<Notification> notifications) {
			this.notifications = notifications;
		}


		public int getCurrentEffort() {
			return currentEffort;
		}


		public void setCurrentEffort(int currentEffort) {
			this.currentEffort = currentEffort;
		}


		public String getSourceCode() {
			return sourceCode;
		}


		public void setSourceCode(String sourceCode) {
			this.sourceCode = sourceCode;
		}


		public String getStepByStep() {
			return stepByStep;
		}


		public void setStepByStep(String stepByStep) {
			this.stepByStep = stepByStep;
		}


		public String getSystemConfiguration() {
			return systemConfiguration;
		}


		public void setSystemConfiguration(String systemConfiguration) {
			this.systemConfiguration = systemConfiguration;
		}


		public String getWorkaround() {
			return workaround;
		}


		public void setWorkaround(String workaround) {
			this.workaround = workaround;
		}


		public Issue getIssue() {
			return issue;
		}


		public void setIssue(Issue issue) {
			this.issue = issue;
		}


		public List<String> getUsersSystem() {
			return usersSystem;
		}


		public void setUsersSystem(List<String> usersSystem) {
			this.usersSystem = usersSystem;
		}


		public Set<String> getTypes() {
			return types;
		}


		public void setTypes(Set<String> types) {
			this.types = types;
		}


		public Set<String> getTeams() {
			return teams;
		}


		public void setTeams(Set<String> teams) {
			this.teams = teams;
		}


		public Set<String> getStatuses() {
			return statuses;
		}


		public void setStatuses(Set<String> statuses) {
			this.statuses = statuses;
		}


		public Set<String> getPriorities() {
			return priorities;
		}


		public void setPriorities(Set<String> priorities) {
			this.priorities = priorities;
		}


		public void setIssueId(int issueId) {
			this.issueId = issueId;
		}


		public Set<String> getIterations() {
			return iterations;
		}


		public void setIterations(Set<String> iterations) {
			this.iterations = iterations;
		}


		public void setIterationSlt(String iterationSlt) {
			this.iterationSlt = iterationSlt;
		}

		public String getIterationSlt() {
			return iterationSlt;
		}

		public String getAddedUser() {
			return addedUser;
		}

		public void setAddedUser(String addedUser) {
			this.addedUser = addedUser;
		}

		public Set<User> getNotificatedUsers() {
			return notificatedUsers;
		}

		public void setNotificatedUsers(Set<User> notificatedUsers) {
			this.notificatedUsers = notificatedUsers;
		}

		public int getUserId() {
			return userId;
		}

		public void setUserId(int userId) {
			this.userId = userId;
		}

		public File getFileUpload() {
			return fileUpload;
		}

		public void setFileUpload(File fileUpload) {
			this.fileUpload = fileUpload;
		}

		public String getFileUploadContentType() {
			return fileUploadContentType;
		}

		public void setFileUploadContentType(String fileUploadContentType) {
			this.fileUploadContentType = fileUploadContentType;
		}

		public String getFileUploadFileName() {
			return fileUploadFileName;
		}

		public void setFileUploadFileName(String fileUploadFileName) {
			this.fileUploadFileName = fileUploadFileName;
		}

		/**
		 * @param attachmentId the attachmentId to set
		 */
		public void setAttachmentId(int attachmentId) {
			this.attachmentId = attachmentId;
		}

		/**
		 * @return the attachmentId
		 */
		public int getAttachmentId() {
			return attachmentId;
		}

		public int getLink() {
			return link;
		}

		public void setLink(int link) {
			this.link = link;
		}

		public int getIssueLinksId() {
			return issueLinksId;
		}

		public void setIssueLinksId(int issueLinksId) {
			this.issueLinksId = issueLinksId;
		}

		public String getComment() {
			return comment;
		}

		public void setComment(String comment) {
			this.comment = comment;
		}
	
}